<template>
  <div class="chat" :class="[inversion === 'user' ? 'self' : 'chatgpt']" v-if="getText || (props.presetQuestion && props.presetQuestion.length>0) || (props.steps && props.steps.length>0) || showTable || props.html">
    <div class="avatar">
      <img v-if="inversion === 'user'" :src="avatar()" />
      <img v-else :src="getAiImg()" />
    </div>
    <div class="content">
      <p class="date">
        <span v-if="inversion === 'ai'" style="margin-right: 10px">{{appData.name || 'AI助手'}}</span>
        <span>{{ dateTime }}</span>
      </p>
      <div v-if="steps && steps.length > 0">
        <a-dropdown trigger="click">
          <a-button type="primary" @click="showCollapse(steps.length - 1)">
            <span v-if="loading">
              <a-icon type="loading-outlined" :spin="true" />
            </span>
            {{ steps[steps.length - 1].title }}
            <a-icon type="down" />
          </a-button>
        </a-dropdown>
        <a-collapse v-model:activeKey="activeKeys" v-if="showCollapsePanel">
          <a-collapse-panel v-for="(item, index) in steps" :key="index" :header="item.time + '  ' + item.title" :panelKey="index.toString()">
            <chatText :text="item.content"></chatText>
          </a-collapse-panel>
        </a-collapse>
      </div>

      <div v-if="showTable" style="width: 100%">
        <JVxeTable ref="tableRef" toolbar resizable maxHeight="400" :toolbarConfig="{ btn: [] }" :columns="columns" :dataSource="dataSource">
          <template #toolbarSuffix>
            <a-button @click="outputData" style="float: right" preIcon="ant-design:export-outlined">导出数据</a-button>
          </template>
        </JVxeTable>
      </div>

      <div class="html-body" v-if="props.html && props.html !== ''" style="width: 800px">
        <a-button @click="outputChart" style="float: right" preIcon="ant-design:export-outlined">导出图表</a-button>
        <iframe :srcdoc="props.html" width="100%" height="100%"></iframe>
      </div>
      <div v-if="inversion === 'user' && images && images.length>0" class="images">
          <div v-for="(item,index) in images" :key="index" class="image" @click="handlePreview(item)">
            <img :src="getImageUrl(item)"/>
          </div>
      </div>
      <div v-if="inversion === 'ai' && retrievalText && loading" class="retrieval">
        {{retrievalText}}
      </div>
      <div v-if="inversion === 'ai' && isCard" class="card">
        <a-row>
          <a-col :xl="6" :lg="8" :md="10" :sm="24" style="flex:1" v-for="item in getCardList()">
            <a-card class="ai-card" @click="aiCardHandleClick(item.linkUrl)">
               <div class="ai-card-title">{{item.productName}}</div>
               <div class="ai-card-img">
                 <img :src="item.productImage">
               </div>
               <span class="ai-card-desc">{{item.descr}}</span>
            </a-card>
          </a-col>
        </a-row>
      </div>
      <div class="msgArea" v-if="!isCard">
        <chatText :text="text" :inversion="inversion" :error="error" :loading="loading" :referenceKnowledge="referenceKnowledge"></chatText>
      </div>
      <div v-if="presetQuestion" v-for="item in presetQuestion" class="question" @click="presetQuestionClick(item.descr)">
        <span>{{item.descr}}</span>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
  import chatText from './chatText.vue';
  import defaultAvatar from "@/assets/images/ai/avatar.jpg";
  import { useUserStore } from '/@/store/modules/user';
  import defaultImg from '../img/ailogo.png';

  const props = defineProps(['dateTime', 'text', 'inversion', 'error', 'loading','appData','presetQuestion','images','retrievalText', 'referenceKnowledge', 'html', 'tableData', 'steps']);
  import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
  import { createImgPreview } from "@/components/Preview";
  // 自定义组件
  import { computed, defineExpose, onMounted, ref, watch } from "vue";
  import { JVxeTypes, JVxeColumn, JVxeTableInstance } from '/@/components/jeecg/JVxeTable/types';
  import { useMethods } from '@/hooks/system/useMethods';
  // 数据表格相关配置
  const tableRef = ref<JVxeTableInstance>();
  const showTable = ref(false);
  const columns = ref<JVxeColumn[]>([]); // 字段列表
  const dataSource = ref<any[]>([]); // 数据列表
  // 流程展示
  const activeKeys = ref([]);
  const showCollapsePanel = ref(false);
  const showCollapse = (index) => {
    showCollapsePanel.value = !showCollapsePanel.value;
    activeKeys.value = [index.toString()];
  };
  // 数据表格 导出excel
  const { handleExportExcel } = useMethods();
  async function outputData() {
    console.log(dataSource.value);
    handleExportExcel('数据导出_' + Date.now() + '.xlsx', dataSource.value);
  }
  function handleTableData() {
    const data_li = props.tableData;
    console.log(44444, data_li);
    if (data_li && data_li.length > 0) {
      columns.value = [];
      const fields = Object.keys(data_li[0]);
      console.log(5555, fields);
      for (let i in fields) {
        const field_key = fields[i];
        columns.value.push({
          title: field_key,
          key: field_key,
          type: JVxeTypes.normal,
          width: 200,
        });
      }
      dataSource.value = data_li;
      showTable.value = true;
    }
  }
  // 渲染表格或html
  function handleData() {
    handleTableData();
  }
  async function outputChart() {
    const output_name = '图表导出_' + Date.now() + '.html';
    const data = new Blob([props.html], { type: 'text/html' });
    const url = URL.createObjectURL(data);
    const link = document.createElement('a');
    link.href = url;
    link.setAttribute('download', output_name);
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  }
  onMounted(() => {
    handleData();
  });
  defineExpose({
    handleData,
  });


  const getText = computed(()=>{
    let text = props.text || props.retrievalText;
    if(text){
      text = text.trim();
    }
    return text;
  })

  const isCard = computed(() => {
    let text = props.text;
    if (text && text.indexOf('::card::') != -1) {
      return true;
    }
    return false;
  });

  const { userInfo } = useUserStore();
  const avatar = () => {
    return getFileAccessHttpUrl(userInfo?.avatar) || defaultAvatar;
  };
  const emit = defineEmits(['send']);
  const getAiImg = () => {
    return getFileAccessHttpUrl(props.appData?.icon) || defaultImg;
  };

  /**
   * 预设问题点击事件
   *
   */
  function presetQuestionClick(descr) {
    emit("send",descr)
  }

  /**
   * 获取图片
   *
   * @param item
   */
  function getImageUrl(item) {
    let url = item;
    if(item.hasOwnProperty('url')){
      url = item.url;
    }
    if(item.hasOwnProperty('base64Data') && item.base64Data){
      return item.base64Data;
    }
    return getFileAccessHttpUrl(url);
  }

  /**
   * 图片预览
   * @param url
   */
  function handlePreview(url){
    const onImgLoad = ({ index, url, dom }) => {
      console.log(`第${index + 1}张图片已加载，URL为：${url}`, dom);
    };
    let imageList = [getImageUrl(url)];
    createImgPreview({ imageList: imageList, defaultWidth: 700, rememberState: true, onImgLoad });
  }

  /**
   * 获取卡片列表
   */
  function getCardList() {
    let text = props.text;
    let card = text.replace('::card::', '').replace(/\s+/g, '');
    try {
      return JSON.parse(card);
    } catch (e) {
      console.log(e)
      return '';
    }
  }

  /**
   * ai卡片点击事件
   * @param url
   */
  function aiCardHandleClick(url){
    window.open(url,'_blank');
  }
  // 监听 tableData 和 html 的变化
  watch(
    () => [props.tableData],
    () => {
      handleData();
    },
    { deep: true }
  );
</script>

<style lang="less" scoped>
  .chat {
    display: flex;
    margin-bottom: 1.5rem;
    &.self {
      flex-direction: row-reverse;
      .avatar {
        margin-right: 0;
        margin-left: 10px;
      }
      .msgArea {
        flex-direction: row-reverse;
      }
      .date {
        text-align: right;
      }
    }
  }
  .avatar {
    flex: none;
    margin-right: 10px;
    img {
      width: 34px;
      height: 34px;
      border-radius: 50%;
      overflow: hidden;
    }
    svg {
      font-size: 28px;
    }
  }
  .content {
    width: 90%;
    .date {
      color: #b4bbc4;
      font-size: 0.75rem;
      margin-bottom: 10px;
    }
    .msgArea {
      display: flex;
    }
  }

  .question{
    margin-top: 10px;
    border-radius: 0.375rem;
    padding-top: 0.5rem;
    padding-bottom: 0.5rem;
    padding-left: 0.75rem;
    padding-right: 0.75rem;
    background-color: #ffffff;
    font-size: 0.875rem;
    line-height: 1.25rem;
    cursor: pointer;
    border: 1px solid #f0f0f0;
    box-shadow: 0 2px 4px #e6e6e6;
  }

  .images{
    margin-bottom: 10px;
    flex-wrap: wrap;
    display: flex;
    gap: 10px;
    justify-content: end;
    .image{
      width: 120px;
      height: 80px;
      cursor: pointer;
      img{
        width: 100%;
        height: 100%;
        object-fit: cover;
        border-radius: 4px;
      }
    }
  }
  .retrieval,
  .card {
    background-color: #f4f6f8;
    font-size: 0.875rem;
    line-height: 1.25rem;
    border-radius: 0.375rem;
    padding-top: 0.5rem;
    padding-bottom: 0.5rem;
    padding-left: 0.75rem;
    padding-right: 0.75rem;
  }
  .retrieval:after{
    animation: blink 1s steps(5, start) infinite;
    color: #000;
    content: '_';
    font-weight: 700;
    margin-left: 3px;
    vertical-align: baseline;
  }
  .card{
    width: 100%;
    background-color: unset;
  }
  .ai-card{
     width: 98%;
     height: 100%;
     cursor: pointer;
    .ai-card-title{
      width: 100%;
      line-height: 20px;
      letter-spacing: 0;
      white-space: pre-line;
      overflow: hidden;
      display: -webkit-box;
      text-overflow: ellipsis;
      -webkit-box-orient: vertical;
      font-weight: 600;
      font-size: 18px;
      text-align: left;
      color: #191919;
      -webkit-line-clamp: 1;
    }
    .ai-card-img{
      margin-top: 10px;
      background-color: transparent;
      border-radius: 8px;
      display: flex;
      width: 100%;
      height: max-content;
    }
    .ai-card-desc{
      margin-top: 10px;
      width: 100%;
      font-size: 14px;
      font-weight: 400;
      line-height: 20px;
      letter-spacing: 0;
      white-space: pre-line;
      -webkit-box-orient: vertical;
      overflow: hidden;
      display: -webkit-box;
      text-overflow: ellipsis;
      text-align: left;
      color: #666f;
      -webkit-line-clamp: 3;
    }
  }
  @media (max-width: 600px) {
    .content{
      width: 100%;
    }
  }
  .html-body {
    height: 500px;
    overflow: scroll;
  }
</style>
